#include <iostream>
#include <zlib/net/I_UnixNetProcessor.h>
#include <unistd.h>
#include <zlib/lib/Ink_sock.h>

using namespace std;

class TestClient : public Continuation
{
public:
	TestClient()
	{
		cout << "TestClient init...." << endl;
		SET_HANDLER(&TestClient::connectEvent);
		buff = new MIOBuffer;
		reader = buff->alloc_reader();
	}

	int connectEvent(int event, void *data)
	{
		vc = (UnixNetVConnect *)data;
		if(event == NET_EVENT_CONNECT)
		{
			cout << "connect success" << endl;
			SET_HANDLER(&TestClient::ioEvent);
			char str[] = "a";
			buff->write(str, strlen(str));
			read_vio = vc->do_io_read(this, buff);
			write_vio = vc->do_io_write(this, reader);
		}else{
			cout << "connect faild" << endl;
			vc->do_io_close(0);
		}
	}

	int ioEvent(int event, void *data)
	{
		//do not use vio
		VIO *vio = (VIO *)data;
		if(event == VC_EVENT_READ_READY)
		{
			cout << "READ_READY.................." << endl;
			IOBufferReader *reader_tmp = reader->clone();
			int64_t len = reader_tmp->read_alive();
			ink_write(2, reader_tmp->start(), len);
			reader_tmp->consum(len);
			reader_tmp->dealloc();
			//echo client
			write_vio->reenable();
		}else if(event == VC_EVENT_READ_COMPLATE)
		{
			cout << "READ_COMPLATE.............." << endl;
			vc->do_io_close(0);
		}else if(event == VC_EVENT_WRITE_READY)
		{
			cout << "WRITE_READY................" << endl;
			//notify read
			read_vio->reenable();
		}else if(event == VC_EVENT_WRITE_COMPLATE)
		{
			cout << "WRITE_COMPLATE........" << endl;
			vc->do_io_close(0);
		}else if(event == VC_EVENT_EOS)
		{
			cout << "EOS EVENT.............." << endl;
			vc->do_io_close(0);
		}else if(event == VC_EVENT_ERROR)
		{
			cout << "ERROR...." << endl;
			vc->do_io_close(0);
		}
	}

private:
	MIOBuffer *buff;
	IOBufferReader *reader;

	UnixNetVConnect *vc;
	VIO *read_vio;
	VIO *write_vio;
};

int main()
{
	eventProcessor.start(1);
	netProcessor.start(0);
	IpEntry client_entry;
	client_entry.init(AF_INET, "127.0.0.1", 8888);
	NetOptions opt;
	TestClient tc;
	tc.mutex = new_ProxyMutex();
	netProcessor.connect_re(&tc, client_entry, opt);

	while(1)
	{
		sleep(10);
	}

	return 0;
}
